package com.namabank.util;

import java.io.*;
import java.security.MessageDigest;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.log4j.Logger;
import org.apache.soap.encoding.soapenc.Base64;

public class EncryptUtil {

    public static byte[] encryptDigest(byte toBeEncrypted[])
            throws Exception {
        byte ret_array[] = null;
        SecretKeySpec skspec = null;
        Cipher l_cipher = null;
        try {
            l_cipher = Cipher.getInstance(enc_method);
            skspec = new SecretKeySpec(l_session_key, enc_method);
            l_cipher.init(1, skspec);
            ret_array = l_cipher.doFinal(toBeEncrypted);
            l_cipher = null;
            skspec = null;
        } catch (Exception e) {
            Logger.getLogger(EncryptUtil.class).error("", e);
        } finally {
            l_cipher = null;
            skspec = null;
        }
        return ret_array;
    }

    public static String encryptWithSessKey(String in_str) {
        try {
            return Base64.encode(encryptDigest(in_str.getBytes("UTF-8")));
        } catch (Exception e) {
            return null;
        }
    }

    public static String tripleDESpwd(String hashStr, String userId)
            throws Exception {
        userId = Base64.encode(userId.getBytes());
        MessageDigest m1 = MessageDigest.getInstance("MD5");
        m1.update(userId.getBytes());
        byte userSeed[] = new byte[24];
        byte digestSeed[] = m1.digest();

        int i = 0, j = 0;
        for (i = 0; i < digestSeed.length; i++) {
            userSeed[i] = digestSeed[i];
        }

        for (i = 16; i < 24; i++) {
            userSeed[i] = userSeed[j];
            j++;
        }
        m1.reset();
        //m1.update(hashStr.getBytes());
        byte pwdSeed[] = new java.math.BigInteger(hashStr, 16).toByteArray();  //.getBytes();//m1.digest();
        if (pwdSeed.length > 16) {
            byte tpwdSeed[] = new byte[16];
            for (i = pwdSeed.length - 1, j = 15; j >= 0; j--, i--) {
                tpwdSeed[j] = pwdSeed[i];
            }
            pwdSeed = tpwdSeed;
        }
        byte encPwd[] = doTripleDES(pwdSeed, userSeed);
        if (encPwd == null) {
            return "";
        }
        MessageDigest m = MessageDigest.getInstance("MD5");
        m.update(encPwd);
        return toHexString(m.digest());
    }

    public static byte[] doTripleDES(byte toBeEncrypted[], byte userSeed[])
            throws Exception {
        toBeEncrypted = Base64.encode(toBeEncrypted).getBytes("UTF-8");
        byte ret_array[] = null;
        SecretKeySpec skspec = null;
        Cipher l_cipher = null;
        try {
            l_cipher = Cipher.getInstance("DESede/ECB/NoPadding");
            skspec = new SecretKeySpec(userSeed, "DESede");
            l_cipher.init(1, skspec);
            ret_array = l_cipher.doFinal(toBeEncrypted);
            l_cipher = null;
            skspec = null;
        } catch (Exception e) {
            Logger.getLogger(EncryptUtil.class).error("Loi khi goi ham doTripleDES", e);
        } finally {
            l_cipher = null;
            skspec = null;
        }
        return ret_array;
    }

    public static String md5(String hashStr)
            throws Exception {
        MessageDigest m = MessageDigest.getInstance("MD5");
        m.update(hashStr.getBytes());
        String hash = new String(m.digest());
        m.reset();
        return hash;
    }

    public static String compressIt(String toBeCompressedIn) {
        byte compressedRequest[] = null;
        byte toBeCompressed[] = toBeCompressedIn.getBytes();
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            GZIPOutputStream gzipoutputstream = new GZIPOutputStream(baos);
            gzipoutputstream.write(toBeCompressed);
            gzipoutputstream.close();
            compressedRequest = baos.toByteArray();
            baos.close();
        } catch (IOException e) {
            Logger.getLogger(EncryptUtil.class).error("", e);
        }
        return Base64.encode(compressedRequest);
    }

    public static String deCompressIt(String toBeDecompressedIn) {
        StringBuilder decompressedResponse = new StringBuilder();
        try {
            byte decodstr[] = Base64.decode(toBeDecompressedIn);
            ByteArrayInputStream bais = new ByteArrayInputStream(decodstr);
            GZIPInputStream gzipinputstream = new GZIPInputStream(bais);
            InputStreamReader reader = new InputStreamReader(gzipinputstream);
            BufferedReader buffReader = new BufferedReader(reader);
            String line;
            while ((line = buffReader.readLine()) != null) {
                decompressedResponse.append(line);
            }
            gzipinputstream.close();
            bais.close();
        } catch (IOException ie) {
            Logger.getLogger(EncryptUtil.class).error("", ie);
        } catch (Exception e) {
            Logger.getLogger(EncryptUtil.class).error("", e);
        }
        return decompressedResponse.toString();
    }

    public static String toHexString(byte bytes[]) {
        String HexChars[] = {
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
            "A", "B", "C", "D", "E", "F"
        };
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            sb.append(HexChars[bytes[i] >> 4 & 0xf]);
            sb.append(HexChars[bytes[i] & 0xf]);
        }

        return new String(sb);
    }
    private static final byte seed[] = {
        105, 45, 102, 108, 101, 120, 32, 115, 111, 108,
        117, 116, 105, 111, 110, 115, 32, 108, 105, 109,
        105, 116, 101, 100
    };
    private static String enc_method = "DESede";
    private static String hash_method = "MD5";
    private static String provider = "SunJCE";
    private static String enc_session_key = null;
    private static byte l_session_key[] = null;
}
